﻿//4.9.2 多义性与解析
//1.命名空间
//只有命名空间在定义域内，我们才能够访问扩展方法。

//例如，下面的扩展方法IsCapitalized：
using System;
namespace Utils
{
    public static class StringHelper
    {
        public static bool IsCapitalized(this string s)
        {
            if (string.IsNullOrEmpty(s)) return false;
            return char.IsUpper(s[0]);
        }
    }
}
//如果要使用IsCapitalized，那么下面的应用程序必须导入Utils，否则会出现编译错误：
namespace MyApp
{
    using Utils;
    class Test
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Perth".IsCapitalized());

            Console.ReadKey();
        }
    }
}

//2.扩展方法与实例方法
//任何兼容的实例方法总是优先于扩展方法。
//在下面的例子中，即使被调用的参数x的类型为int，总是优先调用Test的Foo方法：
class Test
{
    public void Foo(object x) { } //Foo方法总是被调用
}
static class Extensions
{
    public static void Foo(this Test t, int x) { }
}
//在这个例子中，唯一调用扩展方法的方法是通过普通的静态调用语法：即，Extensions.Foo(...)。

//3.扩展方法与扩展方法
// 如果两个扩展方法名称相同，那么扩展方法必须作为一个普通的静态方法调用，才能够区分所调用的方法。然而，如果其中一个扩展方法具有更具体的参数，那么有更具体参数的方法优先级更高。
//例如：下面两个类：
static class StringHelper
{
    public static bool IsCapitalized(this string s) { return default; /*...*/ }
}
static class ObjectHelper
{
    public static bool IsCapitalized(this object s) { return default; /*...*/ }
}
//下面的代码调用StringHelper的IsCapitalized方法
//bool test1 = "Perth".IsCapitalized();
//如果要调用ObjectHelper的IsCapitalized方法，必须明确地定义：
//bool test2 = (ObjectHelper.IsCapitalized("Perth"));
//类型一般比接口更具体一些。